﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpDatabase.h"
#include "GbmpCommon.h"
#include "NdbPropertySchemaType.h"

namespace gcmp
{
    class IIOStream;
    class UniqueWString;

    // 属性schema。保存NdbObject类的成员信息
    class GCMP_DATABASE_EXPORT NdbPropertySchema
    {
    public:
        std::wstring ToWString() const;

        //属性名称Set/Get
        void SetPropertyName(const UniqueWString * propertyName){ m_usPropertyName = propertyName;}
        const UniqueWString * GetPropertyName() const { return m_usPropertyName; }

        //属性类型Set/Get
        void SetPropertyType(const UniqueWString * propertyType){ m_usPropertyType = propertyType;}
        const UniqueWString * GetPropertyType()const { return m_usPropertyType; }

        //属性相对类地址的偏移Set/Get
        void SetOffset(UInt32 offset){ m_offset = offset;}
        UInt32 GetOffset()const{ return m_offset;}

        //属性字节大小Set/Get
        void SetPropertySize(unsigned int propertySize){ m_propertySize = propertySize;}
        UInt32 GetPropertySize()const{ return m_propertySize;}

        NdbPropertySchemaType GetPropertySchemaType() const { return m_propertySchemaType; }
        void SetPropertySchemaType(NdbPropertySchemaType propertySchemaType) { m_propertySchemaType = propertySchemaType; }

        IntOrFloatType GetIntOrFloatType() const { return m_intOrFloatType; }
        void SetIntOrFloatType(IntOrFloatType intOrFloatType) { m_intOrFloatType = intOrFloatType; }

        IntBaseType GetIntBaseType() const { return m_intBaseType; }
        void SetIntBaseType(IntBaseType intBaseType) { m_intBaseType = intBaseType; }

        Int32 GetPropertyBehaviourTypes() const { return m_propertyBehaviourTypes; }
        void SetPropertyBehaviourTypes(Int32 propertyBehaviourTypes) { m_propertyBehaviourTypes = propertyBehaviourTypes; }

        void Serialize(IIOStream & ioStream) const;

        void Unserialize(IIOStream & ioStream);

        bool Compare(const NdbPropertySchema *pPropertySchema) const;

        friend class NdbClassSchemaLibraryUtils;

        NdbPropertySchemaType m_propertySchemaType;
        IntOrFloatType        m_intOrFloatType;
        IntBaseType           m_intBaseType;
        const UniqueWString * m_usPropertyName;
        const UniqueWString * m_usPropertyType;
        UInt32                m_offset;
        UInt32                m_propertySize;
        Int32                 m_propertyBehaviourTypes;
    };

    template <typename T>
    inline const T *GetPropertyAddress(const void *pObject, const NdbPropertySchema &propertySchema)
    {
        return reinterpret_cast<const T *>((char*)pObject + propertySchema.GetOffset());
    }

    template <typename T>
    inline T *GetPropertyAddressFW(void *pObject, const NdbPropertySchema &propertySchema)
    {
        return reinterpret_cast<T *>((char*)pObject + propertySchema.GetOffset());
    }
}
